package com.google.code.syncgear.control;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.google.code.syncgear.core.exception.DatastoreOperationException;
import com.google.code.syncgear.model.Job;
import com.google.code.syncgear.plugin.AbstractDispatch;
import com.google.code.syncgear.plugin.AbstractFetch;
import com.google.code.syncgear.plugin.bean.FetchResult;
import com.google.code.syncgear.util.CacheUtil;

public final class Dispatch implements Serializable {

	private static final long serialVersionUID = -1351348057723959462L;
	
	private static final Logger log = Logger.getLogger(Dispatch.class.getName());
	
	private Job job;
	
	private List<FetchResult> fetchResults;
	
	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}

	public List<FetchResult> getFetchResults() {
		return fetchResults;
	}

	public void setFetchResults(List<FetchResult> fetchResults) {
		this.fetchResults = fetchResults;
	}

	public static boolean execute(String key) {
		Object dispatchObject = CacheUtil.get(key);
		if(dispatchObject != null) {
			Dispatch dispatch = (Dispatch) dispatchObject;
			return dispatch.process(key);
		}
		return false;
	}

	public boolean process(String key) {
		if(job.getLastPubDate() != null) {
			List<FetchResult> temp = new ArrayList<FetchResult>();			
			for(FetchResult fetchResult : fetchResults) {
				if(job.getLastPubDate().before(fetchResult.getPubDate())) {
					temp.add(fetchResult);
				}
			}
			fetchResults = temp;
		}
		if(fetchResults.size() > 0) {
			FetchResult fetchResult = fetchResults.remove(0);			
			try {
				String cacheDispatchName = "DISPATCH" + job.getDispatch();
				Object cacheDispatchObject = CacheUtil.get(cacheDispatchName);
				AbstractDispatch dispatch = null;
				if(cacheDispatchObject == null) {
					dispatch = (AbstractDispatch) Class.forName(job.getDispatch()).newInstance();
					CacheUtil.put(cacheDispatchName, dispatch);
				} else {
					dispatch = (AbstractDispatch) cacheDispatchObject;
				}
				boolean isDispatchSuccess = false;				
				if(job.getLastPubDate() == null) {
					isDispatchSuccess = dispatch.fire(job.getTarget(), fetchResult);					
				} else if(job.getLastPubDate().before(fetchResult.getPubDate())) {
					isDispatchSuccess = dispatch.fire(job.getTarget(), fetchResult);
				}
				if(isDispatchSuccess) {
					job.setLastPubDate(fetchResult.getPubDate());
					this.setJob(job);
					this.setFetchResults(fetchResults);
					CacheUtil.put(key, this);
					if(job.getLastPubDate() != null)
						job.save();
					return true;
				}
			} catch (InstantiationException e) {
				log.warning(e.getMessage());
			} catch (IllegalAccessException e) {
				log.warning(e.getMessage());
			} catch (ClassNotFoundException e) {
				log.warning(e.getMessage());
			} catch (DatastoreOperationException e) {
				log.warning(e.getMessage());
			}
		}
		return false;
	}

}